//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#ifndef __BOOT_DEVICE_H
#define __BOOT_DEVICE_H

#ifdef __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------
//
//  Enumeration:  BOOT_DEVICE_ACCESS
//
enum {
    BOOT_DEVICE_ACCESS_READ = (1 << 0),
    BOOT_DEVICE_ACCESS_WRITE = (1 << 1)
} BOOT_DEVICE_ACCESS;

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_DEINIT
//
//  This function closes persistent store. After this call handle and
//  context are invalid.
//
typedef
BOOL
(*BOOT_DEVICE_PFN_DEINIT)(
    HANDLE hDevice
    );

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_OPEN
//
//  This function opens store. Mode in which store is opened depends on
//  passed context. See BOOT_DEVICE_OPEN_xxx structures for supported modes.
//  Store can be opened only once at same time.
//
typedef
BOOL
(*BOOT_DEVICE_PFN_OPEN)(
    HANDLE hDevice,
    DWORD access,
    DWORD mode,
    VOID *pInfo,
    DWORD infoSize
    );

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_CLOSE
//
//  This function close store. After this call store can be re-opened
//  on different level.
//
typedef
BOOL
(*BOOT_DEVICE_PFN_CLOSE)(
    HANDLE hDevice
    );

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_READ
//
//  Read data from open store at given address.
//
typedef
UINT32
(*BOOT_DEVICE_PFN_READ)(
    HANDLE hDevice,
    VOID* pBuffer,
    UINT32 size
    );

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_WRITE
//
//  Write data to open store at given address.
//
typedef
UINT32
(*BOOT_DEVICE_PFN_WRITE)(
    HANDLE hDevice,
    VOID* pBuffer,
    UINT32 size
    );

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_IOCTL
//
//  This function allows execute implementation/hardware dependant action
//  on store. It should not be used from common libraries.
//
typedef
BOOL
(*BOOT_DEVICE_PFN_IOCTL)(
    HANDLE hDevice,
    DWORD code,
    VOID* pBuffer,
    DWORD size
    );

//------------------------------------------------------------------------------
//
//  Structure:  BOOT_DEVICE_IFC
//
typedef struct BOOT_DEVICE_IFC {
    HANDLE hDevice;
    BOOT_DEVICE_PFN_DEINIT pfnDeinit;
    BOOT_DEVICE_PFN_OPEN   pfnOpen;
    BOOT_DEVICE_PFN_CLOSE  pfnClose;
    BOOT_DEVICE_PFN_READ   pfnRead;
    BOOT_DEVICE_PFN_WRITE  pfnWrite;
    BOOT_DEVICE_PFN_IOCTL  pfnIoCtl;
} BOOT_DEVICE_IFC;

//------------------------------------------------------------------------------
//
//  Function:  BOOT_DEVICE_PFN_INIT
//
//  This function initialize BootStore subsystem. Passed context depends on
//  underlying technology. Function returns handle used for other BootStore
//  calls.
//
typedef
BOOL
(*BOOT_DEVICE_PFN_INIT)(
    VOID* pContext,
    DWORD contextSize,
    BOOT_DEVICE_IFC **ppIfc
    );

//------------------------------------------------------------------------------
//
//  Structure:  BOOT_DEVICE_INIT
//
typedef struct BOOT_DEVICE_INIT {
    BOOT_DEVICE_PFN_INIT pfnInit;
    VOID *pContext;
    DWORD contextSize;
} BOOT_DEVICE_INIT;

//------------------------------------------------------------------------------
//
//  Function: BootDeviceInit
//
//  This is proxy for BOOT_DEVICE_PFN_INIT function.
//
__inline
HANDLE
BootDeviceInit(
    BOOT_DEVICE_INIT* pInit
    )
{
    BOOT_DEVICE_IFC* pIfc = NULL;
    
    if (!pInit->pfnInit(pInit->pContext, pInit->contextSize, &pIfc))
        {
        pIfc = NULL;
        }
    return pIfc;
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceDeinit
//
__inline
BOOL
BootDeviceDeinit(
    HANDLE hDevice
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnDeinit(pIfc->hDevice);
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceIoCtl
//
__inline
BOOL
BootDeviceIoCtl(
    HANDLE hDevice,
    DWORD code,
    VOID* pBuffer,
    DWORD size
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnIoCtl(pIfc->hDevice, code, pBuffer, size);
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceOpen
//
//  This function opens store in raw mode.
//
__inline
BOOL
BootDeviceOpen(
    HANDLE hDevice,
    DWORD access,
    DWORD mode,
    VOID *pContext,
    DWORD contextSize
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnOpen(pIfc->hDevice, access, mode, pContext, contextSize);
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceClose
//
__inline
BOOL
BootDeviceClose(
    HANDLE hDevice
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnClose(pIfc->hDevice);
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceRead
//
__inline
UINT32
BootDeviceRead(
    HANDLE hDevice,
    VOID* pBuffer,
    UINT32 size
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnRead(pIfc->hDevice, pBuffer, size);
}

//------------------------------------------------------------------------------
//
//  Function:  BootDeviceWrite
//
__inline
UINT32
BootDeviceWrite(
    HANDLE hDevice,
    VOID* pBuffer,
    UINT32 size
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hDevice;
    return pIfc->pfnWrite(pIfc->hDevice, pBuffer, size);
}

//------------------------------------------------------------------------------

#ifdef __cplusplus
}
#endif

#endif // __BOOT_DEVICE_H
